package com.whcoding.redis.common;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil<T> {
    private RedisTemplate<String, T> redisTemplate;

    @Autowired
    public RedisUtil(RedisTemplate<String, T> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public boolean setExpireTime(String key, long time) {
        try {
            if (time > 0L) {
                this.redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }

            return true;
        } catch (Exception var5) {
            var5.printStackTrace();
            return false;
        }
    }

    public long getExpireTime(String key) {
        return this.redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    public boolean hasKey(String key) {
        try {
            return this.redisTemplate.hasKey(key);
        } catch (Exception var3) {
            var3.printStackTrace();
            return false;
        }
    }

    public void delete(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                this.redisTemplate.delete(key[0]);
            } else {
                this.redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }

    }

    public T get(String key) {
        return key == null ? null : this.redisTemplate.opsForValue().get(key);
    }

    public boolean set(String key, T value) {
        try {
            this.redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public boolean set(String key, T value, long time) {
        try {
            if (time > 0L) {
                this.redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                this.set(key, value);
            }

            return true;
        } catch (Exception var6) {
            var6.printStackTrace();
            return false;
        }
    }

    public long increase(String key, long delta) {
        if (delta < 0L) {
            throw new RuntimeException("递增因子必须大于0");
        } else {
            return this.redisTemplate.opsForValue().increment(key, delta);
        }
    }

    public long businessCode(int busCode) {
        String dateStr = (new SimpleDateFormat("yyMMdd")).format(new Date());
        String key = busCode + dateStr;
        Long autoNum = this.increase(key, 1L);
        String autoNumStr = String.format("%06d", autoNum);
        Long code = Long.parseLong(key + autoNumStr);
        this.setExpireTime(key, 86400L);
        return code;
    }

    public String createBusinessCode(String busCode, int strLength) {
        String dateStr = (new SimpleDateFormat("yyMMdd")).format(new Date());
        String key = busCode + dateStr;
        Long autoNum = this.increase(key, 1L);
        String autoNumStr = String.format("%0" + strLength + "d", autoNum);
        String businessCode = key + autoNumStr;
        this.setExpireTime(key, 86400L);
        return businessCode;
    }

    public String createBusinessCode(String busCode, Integer supplement, int strLength) {
        String dateStr = (new SimpleDateFormat("yyMMdd")).format(new Date());
        String key = busCode + dateStr + supplement;
        Long autoNum = this.increase(key, 1L);
        String autoNumStr = String.format("%0" + strLength + "d", autoNum);
        String businessCode = key + autoNumStr;
        this.setExpireTime(key, 86400L);
        return businessCode;
    }

    public String increaseStr(String key, int strLength) {
        Long autoNum = this.increase(key, 1L);
        String autoNumStr = String.format("%0" + strLength + "d", autoNum);
        this.setExpireTime(key, 63072000L);
        return autoNumStr;
    }

    public long decrease(String key, long delta) {
        if (delta < 0L) {
            throw new RuntimeException("递减因子必须大于0");
        } else {
            return this.redisTemplate.opsForValue().increment(key, -delta);
        }
    }

    public Object getHash(String key, String item) {
        return this.redisTemplate.opsForHash().get(key, item);
    }

    public Map<Object, Object> getHash(String key) {
        return this.redisTemplate.opsForHash().entries(key);
    }

    public boolean setHash(String key, Map<String, T> map) {
        try {
            this.redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public boolean setHash(String key, Map<String, T> map, long time) {
        try {
            this.redisTemplate.opsForHash().putAll(key, map);
            if (time > 0L) {
                this.setExpireTime(key, time);
            }

            return true;
        } catch (Exception var6) {
            var6.printStackTrace();
            return false;
        }
    }

    public boolean setHash(String key, String item, T value) {
        try {
            this.redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception var5) {
            var5.printStackTrace();
            return false;
        }
    }

    public boolean setHash(String key, String hashKey, T value, long time) {
        try {
            this.redisTemplate.opsForHash().put(key, hashKey, value);
            if (time > 0L) {
                this.setExpireTime(key, time);
            }

            return true;
        } catch (Exception var7) {
            var7.printStackTrace();
            return false;
        }
    }

    public void deleteHash(String key, T... item) {
        this.redisTemplate.opsForHash().delete(key, item);
    }

    public boolean existHash(String key, String item) {
        return this.redisTemplate.opsForHash().hasKey(key, item);
    }

    public double hashIncrease(String key, String hashKey, double by) {
        return this.redisTemplate.opsForHash().increment(key, hashKey, by);
    }

    public double hashDecrease(String key, String hashKey, double by) {
        return this.redisTemplate.opsForHash().increment(key, hashKey, -by);
    }

    public List<T> getList(String key, long start, long end) {
        try {
            return this.redisTemplate.opsForList().range(key, start, end);
        } catch (Exception var7) {
            var7.printStackTrace();
            return null;
        }
    }

    public long getListSize(String key) {
        try {
            return this.redisTemplate.opsForList().size(key);
        } catch (Exception var3) {
            var3.printStackTrace();
            return 0L;
        }
    }

    public T getListByIndex(String key, long index) {
        try {
            return this.redisTemplate.opsForList().index(key, index);
        } catch (Exception var5) {
            var5.printStackTrace();
            return null;
        }
    }

    public boolean setList(String key, T value) {
        try {
            this.redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public boolean setList(String key, T value, long time) {
        try {
            this.redisTemplate.opsForList().rightPush(key, value);
            if (time > 0L) {
                this.setExpireTime(key, time);
            }

            return true;
        } catch (Exception var6) {
            var6.printStackTrace();
            return false;
        }
    }

    public boolean setList(String key, List<T> value) {
        try {
            this.redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public boolean setList(String key, List<T> value, long time) {
        try {
            this.redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0L) {
                this.setExpireTime(key, time);
            }

            return true;
        } catch (Exception var6) {
            var6.printStackTrace();
            return false;
        }
    }

    public boolean updateListByIndex(String key, long index, T value) {
        try {
            this.redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception var6) {
            var6.printStackTrace();
            return false;
        }
    }

    public long deleteListByValue(String key, long count, T value) {
        try {
            Long remove = this.redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception var6) {
            var6.printStackTrace();
            return 0L;
        }
    }

    public Set<T> getSetCache(String key) {
        try {
            return this.redisTemplate.opsForSet().members(key);
        } catch (Exception var3) {
            var3.printStackTrace();
            return null;
        }
    }

    public boolean existSetCache(String key, T value) {
        try {
            return this.redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public long setSetCache(String key, T... values) {
        try {
            return this.redisTemplate.opsForSet().add(key, values);
        } catch (Exception var4) {
            var4.printStackTrace();
            return 0L;
        }
    }

    public long setSetCache(String key, long time, T... values) {
        try {
            Long count = this.redisTemplate.opsForSet().add(key, values);
            if (time > 0L) {
                this.setExpireTime(key, time);
            }

            return count;
        } catch (Exception var6) {
            var6.printStackTrace();
            return 0L;
        }
    }

    public long getSetCacheSize(String key) {
        try {
            return this.redisTemplate.opsForSet().size(key);
        } catch (Exception var3) {
            var3.printStackTrace();
            return 0L;
        }
    }

    public long deleteSetCache(String key, T... values) {
        try {
            Long count = this.redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception var4) {
            var4.printStackTrace();
            return 0L;
        }
    }


}
